<?php
/**
 * MiniBlog helper functions
 * Contains stuff like how to prettify dates and basic text filtering, as well as bootstrapping of the whole system 
 *
 * @version 0.1 
 * @license MIT License http://www.opensource.org/licenses/mit-license.php
 * @copyright (c) 2007 Geir Arne Brevik
 * @author Geir Arne Brevik
 */

//
// Start bootstrapping
//

// set constants
define('MB',true);
$NOW = date("Y-m-d H:i:s",mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y")));

// config file needed for database connection
include_once('config.php');

// autoload classes, and their files
function __autoload($classname)
{
	include_once(strtolower($classname).'.php');
}

// connect to database
$db = DB::getInstance($CONFIG['db_host'], $CONFIG['db_user'], $CONFIG['db_password'], $CONFIG['db_database']);

// in case of install
if (!$db->tableExists('posts')) { MiniBlog::createTable(); }

// parse post requests
if (isset($_POST['action']) and isset($_POST['where'])) {
	$edit	= isset($_POST[$_POST['where']]['id']) ? true : false; // set edit flag
	$post_result = call_user_func_array(array($_POST['where'], $_POST['action']), array($_POST[$_POST['where']], $edit));
	$form_values = isset($post_result['values']) ? $post_result['values'] : false;
	$form_errors = isset($post_result['errors']) ? $post_result['errors'] : false;
}

//
// End bootstrapping
//




/**
 * create a URI safe (and pretty!) string where strange characters are stripped away
 *
 * @param string The string we want to convert
 * @return string the converted string, stripped for non-ASCII text, as well as some other chars that we don't want in our slugs
 * @author Geir Arne Brevik
 **/
function getSlugBase($string)
{
	// make it lowercase and without whitespace in the end and beginning
	$string = strtolower(trim($string));

	// remove non-ascii chars
	$ascii_only = '';
	for($i=0; $i<strlen($string); $i++){
		if(ord($string{$i}) <128){
			$ascii_only .= $string{$i};
		}
	}
	$string = $ascii_only;

	// replace whitespaces, etc with dashes
	$searchfor = array(" ", "	", ".", ",","_", "*", "---", "--");
	$replace   = array("-", "-",   "",  "", "",  "", "-", "-");
	$string = str_replace($searchfor, $replace, $string);

	return $string;
}


/**
 * create a unique, human readable string to act as a alias for the id in the database table in URIs
 *
 * @param string $title - The text we want to base the slug on
 * @param string $table - The table where the slug will reside, and we check uniqueness against
 * @return unique slug
 * @author Geir Arne Brevik
 **/
function getNewSlug($title, $table)
{
	// get initial suggestion
	$init_slug = getSlugBase($title);
	
	$slug = $init_slug;
	
	// check if slug exists, else add number at end of slug
	for ($i = 0; slugExists($slug, $table); $i++) {
		$slug = $init_slug . '-' . $i;
	}
	
	return $slug;
}


/**
 * get ID from given field in a given table 
 *
 * @param string $table The table we're checking
 * @param string $field The field we're looking up the ID for
 * @param mixed $value The (preferably unique) value for the previous field
 * @return int id | bool false
 * @author Geir Arne Brevik
 **/
function getIdFromField($table, $field, $value)
{
	// access the database
	global $CONFIG, $db;
	
	// ask for the user id
	$query = "SELECT id FROM " . $CONFIG['db_prefix'] . $table." WHERE ".$field." = '" . $value . "'";
	$id = $db->getFirstInArray($query);
	
	return $id;
}


/**
 * Check if a text-id, called "slug" exists in a given table
 *
 * @param string $slug - The identifier we want to check for
 * @param string $table - The table we want to check for
 * @param bool $value - wether or not to check against reserved strings in the config array
 * @return bool
 * @author Geir Arne Brevik
 **/
function slugExists($slug, $table, $check_reserved = true)
{
	// database access
	global $db, $CONFIG;
	
	$exists = false;
	
	// check if the slug matches any of the config strings
	if ($check_reserved) {
		foreach($CONFIG as $string) {
			if ($string == $slug) {
				$exists = true;
			}
		}
	}
	
	if (!$exists) {
		// check if the slug is unique
		$query 	= "SELECT COUNT(*) FROM " .$CONFIG['db_prefix']. $table . " WHERE slug = '$slug'";
		$count = $db->getFirstInArray($query);
		// set exists to true
		if ( $count > 0 ) { $exists = true; }
	}
	
	return $exists;
}


/**
 * Prettify date printing, including relative dates
 *
 * @param string MySQL formatted datetime
 * @return string formatted
 * @author 
 **/
function showDate($datetime)
{
	global $NOW;
	
	$datetime = strtotime($datetime);
	$since_hours = 12;
	
    $month_names = array(
        'January', 
        'February', 
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December'
    );
	
    $message_seconds = (($since_hours * 60) * 60);
    $now_diff        = strtotime($NOW) - $message_seconds;
    // nice message if it's a recent datetime
    if ($datetime >= $now_diff and $datetime <= strtotime($NOW)) {
        $diff = strtotime($NOW) - $datetime;
		if ($diff < 1){
			$datetime = __('just now');
		} else if ($diff < 60) { // seconds
            $diff = ($diff == 0 ? $diff++ : $diff);
            $datetime = sprintf($diff == 1? "one second ago" : "%s seconds ago", $diff);
        } else if ($diff < 3600) { // minutes
            $minute = floor($diff/60);
            $datetime = sprintf($minute == 1? "one minute ago" : "%s minutes ago", $minute);    
        } else if ($diff < $message_seconds) { // hours
			$hour = floor(($diff / 60)/60);
            $datetime = sprintf($hour == 1? "one hour ago" : "%s hours ago", $hour);    
        } 
        return($datetime);    
    } else {
        return(date('j.', $datetime) . ' ' . $month_names[date('n', $datetime)-1] . ' @ ' . date('H.i', $datetime));
    }
}

/**
 * Link to user
 *
 * @param int $user user id 
 * @return string html link to list of the user's posts 
 * @author Geir Arne Brevik
 **/
function userLink($user)
{
	return('<a href="./?u='.$user.'">'.$user.'</a>');
}

/**
 * cuts string if too long, and appends something to indicate the cutting
 *
 * @param string $string The text we're checking if we want to cut
 * @param array $args options, such as the number of chars to accept before cutting
 * @return string The finished string, cutted or not
 * @author Geir Arne Brevik
 **/
function cutTooLong($string, $args = array())
{
	global $CONFIG;
	
	$defaults = array('max_length'=>20,					// number of chars to cut after
					  'tail'=>$CONFIG['toolong'], 		// string to append to cutted string
					  'continue_uri'=>false 			// link to this when cut
					  );
	// override default options with supplied arguments
	foreach($args as $arg_key=>$arg_value){ $defaults[$arg_key] = $arg_value; }
	// make readable local variables
	foreach($defaults as $opt_key=>$opt_value){ $$opt_key = $opt_value; }
	
    $string = trim($string);
    $strlen = strlen($string);
	
    if($strlen > $max_length) {
        for($i=1;$string[$max_length-$i]!=" ";$i++) {
            if($i == $max_length) {
                return substr($string,0,$max_length) . $tail;
            }
        }
        for(;$string[$max_length-$i]=="," || $string[$max_length-$i]=="." || $string[$max_length-$i]==" ";$i++) {;}
        $string = substr($string,0,$max_length-$i+1) . $tail;
		$cut = true;
    } else {
		$cut = false;
	}
	// make toolong recognize space before tail
	if((substr($string, -4) == ' '.$tail) or (substr($string, -4) == '.'.$tail)){
		$string = substr($string, 0, -4) . $tail;
	}
	
	// add a "continue" link text
	if($continue_uri and $cut){
		$string = $string.' <a href="'.$continue_uri.'">Continue</a>';
	}
	
	return($string);
}


/**
 * super-simple textfilter. wraps in paragraph, and converts linebreaks to <br>
 * Might be expanded (or replaced) with Textile, Markdown or something similar	
 *
 * @param string $string to be filtered
 * @return string filtered string
 * @author Geir Arne Brevik
 **/
function filter($string)
{
	$searchfor = array("\n");
	$replace   = array("<br>");
	$string = str_replace($searchfor, $replace, $string);
	
	return('<p>'.$string.'</p>');
}

?>